#include "HeartBeatServerImp.h"

#include <iostream> //for log

#include "HeartBeatHandlerImp.h"
#include "DefaultHandlerImp.h"



namespace frame {
namespace imp {


HeartBeatTimerTask::HeartBeatTimerTask(ServerImp * serverImp)
:serverImp(serverImp)
{
}
HeartBeatTimerTask::~HeartBeatTimerTask() {
}

void HeartBeatTimerTask::handle(Timer * timer){
    //std::cout << "timer id:" << getTimerId()  << " beat"  << std::endl;
    HeartBeatServerImp * hbServerImp = static_cast<HeartBeatServerImp*>(serverImp);
    auto channelMaps = hbServerImp->getChannels();
    for(auto & pair : channelMaps){
        pair.second->checkReadTimestamp();
        pair.second->checkWriteTimestamp();
    }
}


HeartBeatServerImp::HeartBeatServerImp(ServerImp * serverImp, uint64_t maxReadTimespan, uint64_t maxWriteTimespan)
: serverImp(serverImp)
, hbHandlerImp(nullptr)
, checkHeartBeatTimerTask(nullptr)
, defaultMaxHeartBeatReadTimespan(maxReadTimespan)
, defaultMaxHeartBeatWriteTimespan(maxWriteTimespan)
{
    std::cout << "HeartBeatServerImp constructor:" << defaultMaxHeartBeatReadTimespan  << " " << defaultMaxHeartBeatWriteTimespan << std::endl;
}
HeartBeatServerImp::~HeartBeatServerImp() {
    if(checkHeartBeatTimerTask != nullptr){
        delete checkHeartBeatTimerTask;
    }
    if(hbHandlerImp != nullptr) {
        delete hbHandlerImp;
    }
}

void HeartBeatServerImp::setHandler(HandlerImp * handler) {
    //Note:???
    hbHandlerImp = new HeartBeatHandlerImp(handler);
    serverImp->setHandler(hbHandlerImp);
    hbHandlerImp->setServerImp(this);
}

int HeartBeatServerImp::start() {
    //set handler hbHandler---> (default Or custome handler);
    HandlerImp * realHandler = serverImp->getHandler() != nullptr ? serverImp->getHandler() : DefaultHandlerImp::instance();
    setHandler(realHandler);

    checkHeartBeatTimerTask = new HeartBeatTimerTask(this);
    addTimerTask(checkHeartBeatTimerTask, 200);
    return serverImp->start();
}
int HeartBeatServerImp::run()  {
    return serverImp->run();
}
void HeartBeatServerImp::stop() {
    serverImp->stop();
    removeTimerTask(checkHeartBeatTimerTask->getTimerId());

    if(checkHeartBeatTimerTask != nullptr){
        delete checkHeartBeatTimerTask;
        checkHeartBeatTimerTask = nullptr;
    }
}

uint64_t HeartBeatServerImp::addTimerTask(ITimerTask * task, uint64_t timespan)  {
    return serverImp->addTimerTask(task, timespan);
}
void HeartBeatServerImp::removeTimerTask(uint64_t timerId)  {
    serverImp->removeTimerTask(timerId);
}





bool HeartBeatServerImp::addChannel(ServerChannelImp * serverChannelImp){
    return getChannels().addChannel(serverChannelImp->getId(), defaultMaxHeartBeatReadTimespan, defaultMaxHeartBeatWriteTimespan, serverChannelImp);
}
bool HeartBeatServerImp::removeChannel(uint64_t channelId){
    return getChannels().removeChannel(channelId);
}
HeartBeatChannelMaps::ChannelNode * HeartBeatServerImp::getChannel(uint64_t channelId){
    return getChannels().getChannel(channelId);
}

} //end of namespace  imp
} //end of namespace  frame
